package com.pwser.shiro;

import java.util.ArrayList;
import java.util.List;

import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.LockedAccountException;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UnknownAccountException;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import com.pwser.po.ShiroUser;
import com.pwser.service.UserService;

@SuppressWarnings("all")
@Component
public class CustomRealm extends AuthorizingRealm {
	
	@Autowired
	private UserService userService;
	
	 /**
     * 角色权限认证（根据用户名查询用户的角色与权限）
     * @param principalCollection
     * @return
     */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection pc) {
		String loginAccount = (String) pc.getPrimaryPrincipal();
		List<String> roles = userService.findRolesByLoginAccount(loginAccount);
		List<String> menus = userService.findMenusByLoginAccount(roles);
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		info.addStringPermissions(menus);
		info.addRoles(roles);
		return info;
	}
	
	/**
     * 登录认证（根据用户名和密码判断用户身份）
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken at) throws AuthenticationException {
		//UsernamePasswordToken对象用来存放提交的登录信息
		UsernamePasswordToken token = (UsernamePasswordToken) at;
		//查出是否有此用户
		ShiroUser user = userService.findUserByLoginAccount(token.getUsername());
		
		if(user == null){
			throw new UnknownAccountException("没有找到该账号");
		}
		
		if("1".equals(user.getLoginStatus())) {
			throw new LockedAccountException("帐号被锁定");
        }
		
		//登录名作盐，相同密码在MD5值不同
		ByteSource salt = ByteSource.Util.bytes(user.getLoginAccount());
		
		//若存在，将此用户存放到登录认证info中
		SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user.getLoginAccount(), user.getLoginPass(), salt, this.getName());
		return info;
	}

	public void setUserService(UserService userService) {
		this.userService = userService;
	}
	
	public static void main(String[] args) {
		String hashAlgorithmName = "MD5";
		int hashIterations = 1024;
		String password = "123";
		ByteSource salt = ByteSource.Util.bytes("wangwu");
		Object obj = new SimpleHash(hashAlgorithmName, password, salt, hashIterations);
		System.out.println(obj);
	}
	
}
